package com.jinzhi.jzapi.common.controller;

import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.configconsts.wxconsts.LinkConfiggure;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.*;
import com.jinzhi.common.vo.WxPayConfig;
import com.jinzhi.common.vo.WxPayVo;
import com.jinzhi.jzweb.domain.OrderDO;
import com.jinzhi.jzweb.domain.OrganizationNewsDO;
import com.jinzhi.jzweb.domain.RecruitmentTopDO;
import com.jinzhi.jzweb.service.OrderService;
import com.jinzhi.jzweb.service.OrganizationNewsService;
import com.jinzhi.jzweb.service.RecruitmentTopService;
import com.jinzhi.jzweb.utils.IdCardUtil;
import com.jinzhi.sys.domain.UserDO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ChainBase;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


@Slf4j
@RestController
@RequestMapping("/jzApi/orgOrder")
public class ApiOrgOrderController extends BaseController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrganizationNewsService organizationNewsService;
    @Autowired
    private RecruitmentTopService recruitmentTopService;
    @Autowired
    private WxPayConfig wxPayConfig;
    @Autowired
    private ChainBase wxPayIsTopChain,wxPayFocusOnChain, wxPayNotifyIsTopChain,wxPayNotifyFocusOnChain;
    @Autowired
    private DictService dictService;
    private static BigDecimal bigDecimal;

    static {
        bigDecimal = new BigDecimal(100);
    }

    /**
    * 管理端-实习就业单位订单提交接口
    *
    * @Description: 实习就业单位订单提交接口 ;参数：机构id，订单类型（0置顶，1关注），置顶天数（置顶特有），置顶开始时间（置顶特有），关注次数（关注特有）
    * @Param: [orgId, type, topDuration, startTime, residues]
    * @return: com.jinzhi.common.utils.ApiResult<?>
    * @Author: kl
    * @Date: 2020-05-14
    */
    @PostMapping("/saveOrder")
    @Log("管理端-实习就业单位订单提交接口")
    @ApiOperation(value = "管理端-实习就业单位订单提交接口", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequiresAuthentication
    @Transactional
    public ApiResult<?> saveOrder(String orgId, String type, String topDuration, String startTime, String residues) {
        //1.根据token获取用户登录数据
        UserDO user = this.getUser();
        if (null == user) {
            return ApiResult.invalid();
        }
        if (null == orgId || orgId == "undefined") {
            return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:orgId");
        }
        if (null == type || type == "undefined") {
            return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:type");
        }

        if (type.equals("0")) {
            if (null == topDuration || topDuration == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:topDuration");
            }
            if (null == startTime || startTime == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:startTime");
            }
        } else {
            //关注简历单独字段
            if (null == residues || residues == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:residues");
            }
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//注意月份是MM
        OrganizationNewsDO organizationNewsDO = organizationNewsService.selectById(Long.parseLong(orgId));
        if (organizationNewsDO != null) {
            Double money = 10.00;
            Map<String, String> map = new HashMap<>();
            if (type.equals("0")) {
                map.clear();
                map.put("name", "置顶金额");
                map.put("type", "top_money");
                String topMoney = dictService.selDicBy(map);
                if (StringUtils.isNotBlank(topMoney)) {
                    //判断是否为数字或小数
                    if (IdCardUtil.isNumericDou(topMoney)) {
                        money = Double.parseDouble(topMoney);
                    }
                }

                //每天的置顶金额乘以置顶天数，为该置顶的支付金额
                money = money * Integer.parseInt(topDuration);
                Map mapssa = new HashMap();
                mapssa.put("orgId",Long.parseLong(orgId));
                mapssa.put("state",0);
                RecruitmentTopDO recruitmentTopDO = recruitmentTopService.selMaxTime(mapssa);
                if (recruitmentTopDO != null) {
                    try {
                        Date startTime1 = simpleDateFormat.parse(startTime);
                        if (startTime1.before(recruitmentTopDO.getEndTime())) {
                            //新设置的开始时间，比最近的结束时间数据要早，提示调整
                            return ApiResult.build(ApiEnumError.SUMBITERR.getCode(), "开始时间比最近购买的结束时间要早，请调整开始时间！");
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                RecruitmentTopDO recruitmentTop = new RecruitmentTopDO();
                recruitmentTop.setOrgId(Long.parseLong(orgId));//机构id
                recruitmentTop.setUserId(user.getId());//操作人
                recruitmentTop.setMoney(money);//置顶金额
                recruitmentTop.setState(1);//默认未支付
                recruitmentTop.setTopDuration(topDuration);//置顶天数

                try {
                    Date startTime1 = simpleDateFormat.parse(startTime);
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.add(Calendar.DATE, Integer.parseInt(topDuration));
                    String endDate = simpleDateFormat.format(calendar2.getTime());
                    Date endTime1 = simpleDateFormat.parse(endDate);
                    recruitmentTop.setStartTime(startTime1);
                    recruitmentTop.setEndTime(endTime1);
                } catch (ParseException e) {
                    e.printStackTrace();
                }

                boolean re = recruitmentTopService.insert(recruitmentTop);
                if (!re) {
                   return ApiResult.build(ApiEnumError.TopSAVEERR.getCode(), ApiEnumError.TopSAVEERR.getMsg());
                }
            }else{
                map.clear();
                map.put("name", "关注金额");
                map.put("type", "focuson_money");
                String focusonMoney = dictService.selDicBy(map);
                if (StringUtils.isNotBlank(focusonMoney)) {
                    //判断是否为数字或小数
                    if (IdCardUtil.isNumericDou(focusonMoney)) {
                        money = Double.parseDouble(focusonMoney);
                    }
                }

                //每天的置顶金额乘以置顶天数，为该置顶的支付金额
                money = money * Integer.parseInt(residues);
            }

            OrderDO orderDO = new OrderDO();
            orderDO.setObjectId(Long.parseLong(orgId));//课程id
            orderDO.setUserId(user.getId());//会员id
            orderDO.setOrderAmount(money);//课程实付金额
            orderDO.setState(1);//默认未付款
            if (type.equals("0")) {
                orderDO.setType(2);
                orderDO.setName(organizationNewsDO.getName() + "-招聘置顶");//课程名
            } else {
                orderDO.setType(3);
                orderDO.setName(organizationNewsDO.getName() + "-关注简历");//课程名
                orderDO.setRemark(residues);
            }

            boolean b = orderService.insert(orderDO);
            if (b) {
                Map map1 = new HashMap();
                map1.put("orderId", orderDO.getId());//订单id
                if (type.equals("0")) {
                    map1.put("topDuration", topDuration);//置顶天数
                } else {
                    map1.put("residues", residues);//关注次数
                }
                return ApiResult.success(map1);
            } else {
                return ApiResult.build(ApiEnumError.SUMBITERR.getCode(), ApiEnumError.SUMBITERR.getMsg());
            }

        } else {
            return ApiResult.build(ApiEnumError.orgsErr.getCode(), ApiEnumError.orgsErr.getMsg());
        }
    }

    /**
    * 管理端-实习就业单位微信支付接口（扫码支付）
    *
    * @Description: 实习就业单位微信支付，参数：微信支付信息集合，机构id，订单类型（0置顶，1关注），置顶天数（置顶特有），关注次数（关注特有）
    * @Param: [wxPayVo, orgId, type, topDuration, residues]
    * @return: com.jinzhi.common.utils.ApiResult<?>
    * @Author: kl
    * @Date: 2020-05-14
    */
    @PostMapping("/wxPay")
    @Log("管理端-实习就业单位微信支付接口（扫码支付）")
    @ApiOperation(value = "管理端-实习就业单位微信支付接口（扫码支付）", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequiresAuthentication
    @Transactional
    public ApiResult<?> wxPay(@Validated WxPayVo wxPayVo, String orderId, String type,String topDuration, String residues) {
        //1.根据token获取用户登录数据
        UserDO user = this.getUser();
        if (null == user) {
            return ApiResult.invalid();
        }
        ApiResult apiResult = new ApiResult();
        try {
            //判断订单id是否为空
            if (null == orderId || orderId == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:orderId");
            }
            //判断类型是否为空
            if (null == type || type == "undefined") {
                return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:type");
            }
            if (type.equals("0")) {
                if (null == topDuration || topDuration == "undefined") {
                    return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:topDuration");
                }
            } else {
                if (null == residues || residues == "undefined") {
                    return ApiResult.build(ApiEnumError.lackParameter.getCode(), "缺少参数:residues");
                }
            }

            Double money = 10.00;
            Map<String, String> map = new HashMap<>();
            if (type.equals("0")) {
                map.clear();
                map.put("name", "置顶金额");
                map.put("type", "top_money");
                String topMoney = dictService.selDicBy(map);
                if (StringUtils.isNotBlank(topMoney)) {
                    //判断是否为数字或小数
                    if (IdCardUtil.isNumericDou(topMoney)) {
                        money = Double.parseDouble(topMoney);
                    }
                }

                //每天的置顶金额乘以置顶天数，为该置顶的支付金额
                money = money * Integer.parseInt(topDuration);

                wxPayVo.setNotify_url(wxPayConfig.getIsTopOrderNotify());//回调地址
            }else{
                map.clear();
                map.put("name", "关注金额");
                map.put("type", "focuson_money");
                String focusonMoney = dictService.selDicBy(map);
                if (StringUtils.isNotBlank(focusonMoney)) {
                    //判断是否为数字或小数
                    if (IdCardUtil.isNumericDou(focusonMoney)) {
                        money = Double.parseDouble(focusonMoney);
                    }
                }

                //每天的置顶金额乘以置顶天数，为该置顶的支付金额
                money = money * Integer.parseInt(residues);

                wxPayVo.setNotify_url(wxPayConfig.getFocusOnOrderNotify());//回调地址
            }

            //通过uuid生成商户id
            String out_trade_no = UUID.randomUUID().toString().replace("-", "");
            //生成32为随机数
            String randomStringBy = StringUtil.getRandomStringByLength(32);

            wxPayVo.setAppid(wxPayConfig.getTraAppid());//appid（微信公众号）
            wxPayVo.setMch_id(wxPayConfig.getMerNo());//商户id
            wxPayVo.setSpbill_create_ip(wxPayConfig.getIp());//ip地址
            wxPayVo.setOut_trade_no(out_trade_no);
            wxPayVo.setNonce_str(randomStringBy);
            wxPayVo.setTotal_fee(new BigDecimal(String.valueOf(money)).multiply(bigDecimal).setScale(0).toString());//支付金额
            wxPayVo.setLabel(WxPayLabelEnum.order.getTag());
            wxPayVo.setType(AppEnum.managing.getTag());

            log.info("商户订单号:" + out_trade_no);

            //保存用户id至缓存，为后面回调提供
            EhCacheUtil.put(out_trade_no + ":orderId", Long.parseLong(orderId));

            //创建上下文
            Context context = new ContextBase();

            //微信支付对象
            context.put(LinkConfiggure.WX_PAY_VO, wxPayVo);
            //固定返回对象
            context.put(LinkConfiggure.API_RESULT, apiResult);
            //机构id
            context.put("orderId", Long.parseLong(orderId));
            //用户id
            context.put("user_id", user.getId());
            //商户订单号
            context.put("out_trade_no", out_trade_no);

            if (type.equals("0")) {
                //置顶天数
                context.put("topDuration", Integer.parseInt(topDuration));
                //开始链路
                wxPayIsTopChain.execute(context);
            } else {
                //关注次数
                context.put("residues", Integer.parseInt(residues));
                //开始链路
                wxPayFocusOnChain.execute(context);
            }

        } catch (Exception e) {
            log.info(e.getMessage());
            throw new RuntimeException(e);
        }
        Map map = new HashMap();
        map.put("type", "wx");
        map.put("wx", apiResult);
        return ApiResult.success(map);
    }

    //招聘置顶微信支付回调
    //    @ExceptionHandler(Exception.class)
    @PostMapping("/isTopWxNotify")
    public String isTopWxNotify(HttpServletRequest request) {
        StringUtil stringUtil = new StringUtil();
        return stringUtil.getWxNotify(request, wxPayNotifyIsTopChain, wxPayConfig);
    }

    //关注简历微信支付回调
    //    @ExceptionHandler(Exception.class)
    @PostMapping("/focusOnWxNotify")
    public String focusOnWxNotify(HttpServletRequest request) {
        StringUtil stringUtil = new StringUtil();
        return stringUtil.getWxNotify(request, wxPayNotifyFocusOnChain, wxPayConfig);
    }

    /**
    * 管理端-实习就业单位订单状态查询接口
    *
    * @Description: 实习就业单位订单状态查询接口；参数：订单id
    * @Param: [id]
    * @return: com.jinzhi.common.utils.ApiResult<?>
    * @Author: kl
    * @Date: 2020-05-14
    */
    @GetMapping("/selOrderState")
    @Log("管理端-实习就业单位订单状态查询接口")
    @ApiOperation(value = "管理端-实习就业单位订单状态查询接口", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequiresAuthentication
    @Transactional
    public ApiResult<?> selOrderState(String id) {
        if(id == null){
            return ApiResult.fail("参数缺失");
        }
        OrderDO orderDO = orderService.selectById(Long.parseLong(id));
        if (orderDO != null) {
            return ApiResult.success(orderDO.getState());
        } else {
            return ApiResult.build(ApiEnumError.NoInfrom.getCode(), ApiEnumError.NoInfrom.getMsg());
        }
    }

}
